package com.greatchn.authorization_server.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.greatchn.authorization_server.constant.Constant;
import com.greatchn.authorization_server.util.ServiceAssert;
import com.greatchn.authorization_server.web.po.OauthFunctionInfo;
import com.greatchn.authorization_server.web.po.OauthRoleGroupInfo;
import com.greatchn.authorization_server.web.srv.OauthConfigSrv;
import com.greatchn.authorization_server.web.srv.OauthFunctionInfoSrv;
import com.greatchn.authorization_server.web.srv.OauthRoleFunctionConnectionSrv;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @FilterMetadataSource: 设置角色权限
 * @author: ZBoHang
 * @time: 2023/2/9 16:50
 */
@Order
@Component("metadataSourceHandler")
public class MetadataSourceHandler implements FilterInvocationSecurityMetadataSource {

    @Resource
    private OauthConfigSrv oauthConfigSrv;
    @Resource
    private OauthRoleFunctionConnectionSrv oauthRoleFunctionConnectionSrv;
    @Resource
    private OauthFunctionInfoSrv oauthFunctionInfoSrv;


    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) {
        //获取请求的url
        String requestUrl = ((FilterInvocation) object).getRequestUrl();
        String noAuthenticationPathStr = this.oauthConfigSrv.getValidConfigByKey("no_authentication_path_str").getValue();
        // 首先匹配 不需要认证的url
        List<String> noAuthenticationPathList = StrUtil.split(noAuthenticationPathStr, StrUtil.COMMA);
        boolean matchResult = noAuthenticationPathList.stream().anyMatch(url -> Constant.ANTPATHMATCHER.match(url, requestUrl));
        // 不需要认证的url 返回默认角色
        if (matchResult) {
            return SecurityConfig.createList(Constant.DEFAULT_ROLE);
        }
        // 匹配url的所有功能
        List<OauthFunctionInfo> oauthFunctionInfoList = this.oauthFunctionInfoSrv.getAll()
                .stream()
                .filter(vo -> Constant.ANTPATHMATCHER.match(vo.getFunctionName(), requestUrl))
                .collect(Collectors.toList());
        // 查询功能对应的角色
        List<String> conformingRoleList =
                this.oauthRoleFunctionConnectionSrv.getAllRoleIdByFunctionIds(
                        oauthFunctionInfoList.stream().map(OauthFunctionInfo::getFunctionId).collect(Collectors.toList())
                ).stream().map(OauthRoleGroupInfo::getRoleGroupName).collect(Collectors.toList());
        //没匹配的url 路径异常
        ServiceAssert.isFalse(CollUtil.isEmpty(conformingRoleList), "路径异常!");

        return SecurityConfig.createList(conformingRoleList.toArray(new String[0]));
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }
}
